package ij.umasuo.AOTFController;

import ij.IJ;
import ij.Prefs;

import java.io.IOException;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RMISecurityManager;
import java.rmi.RemoteException;

/**
 * this class is used to control the AOTF
 * @author LiuQuan
 * @date 2013/08/07
 * @version 1.0
 * @Test the process' start and destroy
 */
public class AOTFClient {
	
	MyAOTFCtrInteface aotf;
	private static AOTFClient instance = null;
	public static Process process = null;
	
	private AOTFClient(){
		try {
			Runtime rm =Runtime.getRuntime();
			String homeDir =  Prefs.getHomeDir();
			//my.policy and AOTFCtr.jar file must be the same directory with ij.jar, and we also need a 32 bit jre in the directory
//			String cmd = homeDir + "\\jre32\\bin\\javaw.exe -Djava.security.manager -Djava.security.policy=" + homeDir + "\\my.policy -jar " + homeDir + "\\AOTFCtr.jar";
			String cmd = "E:\\ProgramSpace\\jre7\\bin\\javaw.exe -Djava.security.manager -Djava.security.policy=E:/ProgramSpace/my.policy -jar C:\\Users\\storm\\Desktop\\AOTFCtr.jar";
			process = rm.exec(cmd);//start the 32bit jvm, this jvm provide the interface for us to call the aotfContoller
		} catch (Exception e) {
			IJ.error("AOTF ERROR", "init the AOTF ERROR." + e.toString());
		}

	}
	
	/**
	 * init the AOTF, reset all lasers
	 */
	public void resetAOTF(){
		try{
			if(!checkAotf()){
				IJ.error("AOTF ERROR", "Can not reset the AOTF.\n");
			}
			aotf.Write("dau dis\r");
			aotf.Write("dau en\r");
			aotf.Write("dau gain * 255\r");
			aotf.Write("dds a 0 0\r");
			aotf.Write("dds a 1 0\r");
			aotf.Write("dds a 2 0\r");
			aotf.Write("dds a 3 0\r");
			aotf.Write("dds a 4 0\r");
			aotf.Write("dds a 5 0\r");
			
			aotf.Write("dds f 0 153.7560\r");
			aotf.Write("dds f 1 123.1750\r");
			aotf.Write("dds f 2 113.7680\r");
			aotf.Write("dds f 3 99.2574\r");
			aotf.Write("dds f 4 93.6800\r");
			aotf.Write("dds f 5 77.3082\r");
		}catch(Exception e){
			IJ.error("AOTF ERROR", "Can not reset the AOTF.\n" + e.toString());
		}
		
	}
	
	/**
	 * open the aotfController
	 * @return
	 */
	public boolean Open() {
		try {
			if(!checkAotf()){
				return false;
			}
			return aotf.Open();
		} catch (Exception e) {
			IJ.error("AOTF ERROR", "Can not open the AOTF.\n" + e.toString());
			return false;
		}
	}

	/**
	 * close the aotfController
	 * @return
	 */
	public boolean Close() {
		try {
			if(aotf != null){
				resetAOTF();
				aotf.Write("dau dis\r");
				aotf.Close();//close the aotf
			}
			process.destroy();//stop the 32bit java jvm which used to control the AOTF
			return true;
		} catch (Exception e) {
			IJ.error("AOTF ERROR", "Can not open the AOTF.\n" + e.toString());
			return false;
		}
	}

	/**
	 * write the command to the aotfController
	 * @param command
	 * @return
	 */
	public boolean Write(String command) {
		try {
			if(!checkAotf()){
				return false;
			}
			if(command == null){
				IJ.error("AOTF ERROR","aotf write command is null!!");
			}
			return aotf.Write(command);
		} catch (Exception e) {
			IJ.error("AOTF ERROR", "Can not open the AOTF.\n" + e.toString());
			return false;
		}
	}

	/**
	 * check if the aotfContorller has been opened
	 * @return
	 */
	public boolean IsOpen() {
		try {
			if(!checkAotf()){
				return false;
			}
			return aotf.IsOpen();
		} catch (Exception e) {
			IJ.error("AOTF ERROR", "Can not open the AOTF.\n" + e.toString());
			return false;
		}
	}

	/**
	 * check if we have got the aotfController instance
	 * @return
	 */
	public boolean checkAotf(){
		if(aotf == null){
			try {
				aotf = (MyAOTFCtrInteface) Naming.lookup("//127.0.0.1:8802/MYAOTFCTR");
				if(aotf == null){
					return false;
				}
				aotf.Open();
			} catch (Exception e) {
				IJ.error("AOTF ERROR","get the aotf error.\n" + e.toString());
				return false;
			}
		}
		return true;
	}
	
	/**
	 * get the instance
	 * @return
	 */
	public static AOTFClient getInstance(){
		if(instance == null){
			instance = new AOTFClient();
		}
		return instance;
	}
	
	
	public static void main(String[] args){
		AOTFClient test = new AOTFClient();
		test.resetAOTF();
		boolean oret = test.Open();
		while(true){
			boolean ret = test.Write("dds a 5 2000\r");
			try {
				Thread.currentThread().sleep(500);
			} catch (InterruptedException e) {
				// Auto-generated catch block
				e.printStackTrace();
			}
			test.Write("dds a 5 0\r");
		}
		
	}
}
